package bid

import (
	"encoding/json"
	"errors"
	"strconv"
	"strings"
	"time"
	"wx-api/adx-bid/models/bid/BidModel"
	"wx-api/adx-bid/models/dsp/360ad/Ad360Model"
	"wx-api/adx-bid/utils"
)

type Ad360 struct{}

func (z *Ad360) Req(p *BudgetService) (data []byte, hd map[string]string, surl, method string, tms int, err error) {
	surl = p.Dsp.BidUrl
	method = "POST"
	tms = 350
	hd = make(map[string]string)
	hd["Content-Type"] = "application/json"
	data, err = z.ReqData(p)
	return data, hd, surl, method, tms, err
}
func (z *Ad360) ReqData(p *BudgetService) ([]byte, error) {
	t := p.Req
	reqid := z.GetRequestId(p.Pos.MediaId, p.Pos.AdvId)
	m := Ad360Model.BidRequest{
		RequestId: reqid,
		Auth:      z.GetAuth(reqid, p.Dsp.Token),
		Timeout:   350,
		Version:   "1.4.4",
	}
	if t.GetDevice() != nil {
		d := t.GetDevice()
		m.Device = &Ad360Model.BidRequest_Device{
			DeviceId: "",
			Network: func(a string) int32 {
				switch d.GetConnectionType() {
				case "2g":
					return 2
				case "3g":
					return 3
				case "4g":
					return 4
				case "5g":
					return 5
				}
				return 6
			}(d.GetConnectionType()),
			DeviceType:   1,
			Imei:         d.GetImei(),
			ImeiMd5:      d.GetImeiMd5(),
			Idfa:         d.GetIdfa(),
			IdfaMd5:      d.GetIdfaMd5(),
			AndroidId:    d.GetAndroidId(),
			AndroidIdMd5: d.GetAndroidIdMd5(),
			Oaid:         d.GetOaid(),
			OaidMd5:      d.GetOaidMd5(),
			Caids: func(a []*BidModel.BidRequest_Device_Caid) *Ad360Model.BidRequest_Device_Caid {
				if a == nil {
					return nil
				}
				for _, i2 := range a {
					if i2.GetCaid() != "" || i2.GetCaidMd5() != "" {
						return &Ad360Model.BidRequest_Device_Caid{
							Caid:        i2.GetCaid(),
							CaidVersion: i2.GetCaidVersion(),
						}
					}
				}
				return nil
			}(d.GetCaids()),
			Brand: d.GetBrand(),
			Model: d.GetModel(),
			Os: func(a string) string {
				if strings.ToLower(a) == "ios" {
					return "ios"
				}
				return "android"
			}(d.GetOs()),
			OsVersion: d.GetOsv(),
			Carrier: func(a string) int32 {
				switch d.GetCarrier() {
				case "70123":
					return 2
				case "70121":
					return 3
				}
				return 1
			}(d.GetCarrier()),
			Mac:    d.GetMac(),
			MacMd5: d.GetMacMd5(),
			Ip: func(a, b string) string {
				if a != "" {
					return a
				}
				return b
			}(d.GetIp(), d.GetIpv6()),
			UserAgent: d.GetUa(),
			Geo: func(a *BidModel.BidRequest_Geo) *Ad360Model.BidRequest_Device_Geo {
				if a == nil {
					return nil
				}
				return &Ad360Model.BidRequest_Device_Geo{
					Latitude:  a.GetLat(),
					Longitude: a.GetLon(),
				}
			}(d.GetGeo()),
			Orientation: func(a int32) int32 {
				if a == 180 {
					return 2
				}
				return 1
			}(d.GetOrientation()),
			ScreenWidth:     d.GetW(),
			ScreenHeight:    d.GetH(),
			BootMark:        d.GetBootMark(),
			UpdateMark:      d.GetUpdateMark(),
			SyscoreVersion:  d.GetVersionCodeHms(),
			AppstoreVersion: d.GetVersionCodeAg(),
		}
		if m.GetDevice().GetOs() == "ios" {
			m.Device.DeviceId = d.GetIdfaMd5()
		} else {
			if d.GetOaidMd5() != "" {
				m.Device.DeviceId = d.GetOaidMd5()
			} else {
				m.Device.DeviceId = d.GetImeiMd5()
			}
		}
		if d.GetBrand() == "" && d.GetMake() != "" {
			m.Device.Brand = d.GetMake()
		}
	}
	imp := &Ad360Model.BidRequest_Imp{
		Id:     1,
		Width:  int32(p.Pos.Width),
		Height: int32(p.Pos.Height),
		Count:  1,
	}
	m.Imps = append(m.Imps, imp)
	if t.GetApp() != nil {
		app := t.GetApp()
		m.App = &Ad360Model.BidRequest_App{
			AppName: func(a, b string) string {
				if a != "" {
					return a
				}
				return b
			}(p.Pos.AppName, app.GetName()),
			PkgName: func(a, b string) string {
				if a != "" {
					return a
				}
				return b
			}(p.Pos.Package, app.GetBundle()),
			Version: func(a, b string) string {
				if a != "" {
					return a
				}
				return b
			}(p.Pos.AppVersion, app.GetVer()),
		}
	}
	//竞价
	if p.IsRtb {
		m.Imps[0].Bidfloor = p.MSPrice
		if p.MSPrice == 0 {
			return nil, errors.New("ad360 param Bidfloor 0")
		}
	}
	tm, err := json.Marshal(&m)
	if err != nil {
		return nil, err
	}
	return tm, nil
}
func (z *Ad360) Res(p *BudgetService, tmpbody []byte) (*BidModel.BidResponse_SeatBid_Bid, error) {
	m := &Ad360Model.BidResponse{}
	err := json.Unmarshal(tmpbody, m)
	if err != nil {
		return nil, err
	}
	if m.GetCode() != 0 {
		return nil, errors.New("ad360 code error:" + m.GetMessage())
	}
	if m.GetData() == nil {
		return nil, errors.New("ad360 data empty")
	}
	if len(m.GetData().GetGroups()) == 0 {
		return nil, errors.New("ad360 data group empty")
	}
	if len(m.GetData().GetGroups()[0].GetAds()) == 0 {
		return nil, errors.New("ad360 data group ads empty")
	}
	ad := m.GetData().GetGroups()[0].GetAds()[0]
	tmpbid := &BidModel.BidResponse_SeatBid_Bid{
		Id:        p.Req.GetId(),
		Impid:     "1",
		Adid:      strconv.Itoa(int(ad.GetId())),
		Price:     ad.GetPrice(),
		Cid:       ad.GetCreativeId(),
		Title:     ad.GetTitle(),
		Desc:      ad.GetDesc(),
		Clicktype: "1",
		ClickUrl:  ad.GetLink(),
		Views:     ad.GetImpTrackUrls(),
		Clicks:    ad.GetClickTrackUrls(),
		W:         ad.GetAdWidth(),
		H:         ad.GetAdHeight(),
		//Source:      ad.GetSource(),
	}
	for _, image := range ad.GetImgs() {
		tmpbid.Imgs = append(tmpbid.Imgs, &BidModel.BidResponse_SeatBid_Bid_Image{
			Url: image.GetUrl(),
			W:   image.GetWidth(),
			H:   image.GetHeight(),
		})
	}
	if ad.GetVideo() != nil {
		tmpbid.Video = &BidModel.BidResponse_SeatBid_Bid_Video{
			Url:      ad.GetVideo().GetVideoUrl(),
			Duration: int32(ad.GetVideo().GetDuration() / 1000),
			W:        ad.GetVideo().GetWidth(),
			H:        ad.GetVideo().GetHeight(),
			Cimg: &BidModel.BidResponse_SeatBid_Bid_Image{
				Url: ad.GetVideo().GetCoverUrl(),
				W:   ad.GetVideo().GetWidth(),
				H:   ad.GetVideo().GetHeight(),
			},
			Ext: &BidModel.BidResponse_SeatBid_Bid_Video_VideoExt{
				Start: func(a []*Ad360Model.BidResponse_Data_Group_Ad_EventTrack) []string {
					if len(a) == 0 {
						return nil
					}
					for _, track := range a {
						if track.GetEventType() == 1 {
							return track.GetEventTrackUrls()
						}
					}
					return nil
				}(ad.GetAppInfo().GetEventTracks()),
				End: func(a []*Ad360Model.BidResponse_Data_Group_Ad_EventTrack) []string {
					if len(a) == 0 {
						return nil
					}
					for _, track := range a {
						if track.GetEventType() == 2 {
							return track.GetEventTrackUrls()
						}
					}
					return nil
				}(ad.GetAppInfo().GetEventTracks()),
			},
		}
	}
	if ad.GetAppInfo() != nil {
		app := ad.GetAppInfo()
		tmpbid.App = &BidModel.BidResponse_SeatBid_Bid_App{
			Name: app.GetName(),
			Pkg:  app.GetPkgName(),
			Icon: app.GetLogoUrl(),
			Dev:  app.GetSoftCorpName(),
			Pri:  app.GetSensitiveUrl(),
			Per:  app.GetUsesPermission(),
			Ver:  app.GetVersion(),
			Size: int32(app.GetSize()),
		}
		tmpbid.DownUrl = app.GetDownUrl()
		tmpbid.StartDown = app.GetDsUrls()
		tmpbid.EndDown = app.GetDfUrls()
		tmpbid.StartInstall = app.GetSsUrls()
		tmpbid.EndInstall = app.GetSfUrls()
		tmpbid.Dpurl = app.GetDeepLink()
		tmpbid.DplinksSuccess = func(a []*Ad360Model.BidResponse_Data_Group_Ad_EventTrack) []string {
			if len(a) == 0 {
				return nil
			}
			for _, track := range a {
				if track.GetEventType() == 14 {
					return track.GetEventTrackUrls()
				}
			}
			return nil
		}(app.GetEventTracks())
		tmpbid.DplinksFalid = func(a []*Ad360Model.BidResponse_Data_Group_Ad_EventTrack) []string {
			if len(a) == 0 {
				return nil
			}
			for _, track := range a {
				if track.GetEventType() == 13 {
					return track.GetEventTrackUrls()
				}
			}
			return nil
		}(app.GetEventTracks())
	}
	if tmpbid.GetDpurl() != "" {
		tmpbid.Clicktype = "2"
	}
	return tmpbid, nil
}

func (z *Ad360) GetAuth(requestid, token string) string {
	return strings.ToUpper(utils.MD5(requestid + token))
}
func (z *Ad360) GetRequestId(platid, slotid string) string {
	return z.GetPlatformId(platid) + z.GetSlotId(slotid) + strconv.FormatInt(time.Now().UnixNano()/1e6, 10)
}
func (z *Ad360) GetSlotId(a string) string {
	if len(a) == 1 {
		return "000000" + a
	}
	if len(a) == 2 {
		return "00000" + a
	}
	if len(a) == 3 {
		return "0000" + a
	}
	if len(a) == 4 {
		return "000" + a
	}
	if len(a) == 5 {
		return "00" + a
	}
	if len(a) == 6 {
		return "0" + a
	}
	return a
}
func (z *Ad360) GetPlatformId(a string) string {
	if len(a) == 1 {
		return "0000" + a
	}
	if len(a) == 2 {
		return "000" + a
	}
	if len(a) == 3 {
		return "00" + a
	}
	if len(a) == 4 {
		return "0" + a
	}
	return a
}
